import { Injectable, inject } from '@angular/core';
import { TuiMobileDialogService } from '@taiga-ui/addon-mobile';

// 定义业务场景配置接口
interface BusinessScenarioConfig {
  // 基础配置
  key: string; // 业务场景唯一标识
  title?: string; // 弹窗标题
  defaultContent: string; // 默认内容
  defaultActions?: string[]; // 默认按钮

  // 弹窗频率控制
  maxShowPerDay?: number; // 每天最多显示次数，默认为3次
  firstPopupInterval?: number; // 第一次弹出后的间隔时间（分钟），未设置则立即弹出
  secondPopupInterval?: number; // 第二次弹出后的间隔时间（分钟），未设置则使用firstPopupInterval

  // 高级配置
  enabled?: boolean; // 是否启用该场景
  expireDate?: Date; // 过期时间，超过该时间不再显示
  priority?: number; // 优先级，数字越大优先级越高
  showCount?: number; // 已显示次数
}

// 记录每个场景的弹窗记录
interface PopupRecord {
  date: string; // 记录日期（YYYY-MM-DD格式）
  times: number[]; // 当天弹出的时间戳数组
}

@Injectable({
  providedIn: 'root',
})
export class TimerDialogService {
  private readonly dialogService = inject(TuiMobileDialogService);
  private popupRecords: Record<string, PopupRecord> = {}; // 弹窗记录
  private scenarios: Record<string, BusinessScenarioConfig> = {}; // 场景配置

  // 存储路径
  private readonly STORAGE_RECORDS_KEY = 'dialogPopupRecords';
  private readonly STORAGE_SCENARIO_KEY = 'dialogScenarios';

  constructor() {
    this._loadFromStorage();
  }

  /**
   * 从存储中加载数据
   */
  private _loadFromStorage() {
    try {
      // 从localStorage恢复弹窗记录
      const savedRecords = localStorage.getItem(this.STORAGE_RECORDS_KEY);
      if (savedRecords) {
        this.popupRecords = JSON.parse(savedRecords);

        // 清理过期记录（非当天的记录）
        const today = this._getTodayKey();
        Object.keys(this.popupRecords).forEach((scenarioKey) => {
          if (this.popupRecords[scenarioKey].date !== today) {
            // 如果记录不是今天的，重置为今天的空记录
            this.popupRecords[scenarioKey] = {
              date: today,
              times: [],
            };
          }
        });
        this._savePopupRecords();
      }

      // 从localStorage恢复场景配置
      const savedScenarios = localStorage.getItem(this.STORAGE_SCENARIO_KEY);
      if (savedScenarios) {
        this.scenarios = JSON.parse(savedScenarios);

        // 处理Date类型
        Object.values(this.scenarios).forEach((scenario) => {
          if (scenario.expireDate) {
            scenario.expireDate = new Date(scenario.expireDate);
          }
        });
      }
    } catch (error) {
      console.error('恢复弹窗数据出错:', error);
      // 发生错误时重置数据
      this.popupRecords = {};
      this.scenarios = {};
    }
  }

  /**
   * 获取今天的日期键（YYYY-MM-DD格式）
   */
  private _getTodayKey(): string {
    const now = new Date();
    return `${now.getFullYear()}-${String(now.getMonth() + 1).padStart(
      2,
      '0'
    )}-${String(now.getDate()).padStart(2, '0')}`;
  }

  /**
   * 注册业务场景
   * @param config 业务场景配置
   */
  registerScenario(config: BusinessScenarioConfig) {
    if (!config.key) {
      console.error('业务场景必须提供唯一key');
      return;
    }

    // 合并已有配置（如果存在）
    const existingConfig = this.scenarios[config.key];
    this.scenarios[config.key] = {
      ...existingConfig,
      ...config,
      // 设置默认值
      maxShowPerDay: config.maxShowPerDay ?? 3,
      enabled: config.enabled !== undefined ? config.enabled : true,
      priority: config.priority !== undefined ? config.priority : 0,
    };

    // 保存到localStorage
    this._saveScenarios();
  }

  /**
   * 获取业务场景配置
   * @param key 业务场景唯一标识
   */
  getScenario(key: string): BusinessScenarioConfig | undefined {
    return this.scenarios[key];
  }

  /**
   * 更新业务场景配置
   * @param key 业务场景唯一标识
   * @param updates 要更新的配置项
   */
  updateScenario(key: string, updates: Partial<BusinessScenarioConfig>) {
    if (this.scenarios[key]) {
      this.scenarios[key] = {
        ...this.scenarios[key],
        ...updates,
      };
      this._saveScenarios();
    }
  }

  /**
   * 禁用业务场景
   * @param key 业务场景唯一标识
   */
  disableScenario(key: string) {
    if (this.scenarios[key]) {
      this.scenarios[key].enabled = false;
      this._saveScenarios();
    }
  }

  /**
   * 启用业务场景
   * @param key 业务场景唯一标识
   */
  enableScenario(key: string) {
    if (this.scenarios[key]) {
      this.scenarios[key].enabled = true;
      this._saveScenarios();
    }
  }

  /**
   * 重置业务场景的弹窗记录
   * @param key 业务场景唯一标识
   */
  resetScenario(key: string) {
    if (this.scenarios[key]) {
      // 重置弹窗记录
      this.popupRecords[key] = {
        date: this._getTodayKey(),
        times: [],
      };
      this._savePopupRecords();
    }
  }

  /**
   * 检查是否满足弹窗条件
   * @param key 业务场景唯一标识
   * @param forceShow 是否强制显示
   */
  private _canShowPopup(key: string, forceShow: boolean = false): boolean {
    const scenario = this.scenarios[key];
    if (!scenario) {
      console.error(`业务场景 ${key} 未注册`);
      return false;
    }

    if (!scenario.enabled && !forceShow) {
      console.log(`业务场景 ${key} 已禁用`);
      return false;
    }

    // 检查过期时间
    if (scenario.expireDate && new Date(scenario.expireDate) < new Date()) {
      return false;
    }

    // 如果强制显示，则跳过频率检查
    if (forceShow) {
      return true;
    }

    const today = this._getTodayKey();

    // 确保该场景的记录对象存在
    if (!this.popupRecords[key] || this.popupRecords[key].date !== today) {
      this.popupRecords[key] = {
        date: today,
        times: [],
      };
    }

    const record = this.popupRecords[key];
    const now = Date.now();

    // 检查当天弹出次数限制
    if (record.times.length >= (scenario.maxShowPerDay || 3)) {
      return false;
    }

    // 检查弹出间隔
    if (record.times.length > 0) {
      const lastPopupTime = record.times[record.times.length - 1];

      // 根据当前是第几次弹出来确定间隔时间
      let intervalMinutes = 0;

      if (record.times.length === 1) {
        // 第一次弹出后，准备第二次弹出时的间隔
        intervalMinutes = scenario.firstPopupInterval || 0;
      } else if (record.times.length === 2) {
        // 第二次弹出后，准备第三次弹出时的间隔
        intervalMinutes =
          scenario.secondPopupInterval || scenario.firstPopupInterval || 0;
      }

      const intervalMs = intervalMinutes * 60 * 1000;
      if (intervalMinutes > 0 && now - lastPopupTime < intervalMs) {
        return false;
      }
    }

    return true;
  }

  /**
   * 记录弹窗显示
   * @param key 业务场景唯一标识
   */
  private _recordPopup(key: string) {
    const today = this._getTodayKey();

    // 确保该场景的记录对象存在且是今天的
    if (!this.popupRecords[key] || this.popupRecords[key].date !== today) {
      this.popupRecords[key] = {
        date: today,
        times: [],
      };
    }

    // 记录当前弹出时间
    this.popupRecords[key].times.push(Date.now());
    this._savePopupRecords();
  }

  /**
   * 根据业务场景显示弹窗
   * @param key 业务场景唯一标识
   * @param options 覆盖配置（可选）
   */
  showByScenario(
    key: string,
    options?: {
      content?: string;
      title?: string;
      actions?: string[];
      forceShow?: boolean; // 是否强制显示（忽略时间间隔等限制）
    }
  ) {
    // 检查是否满足弹窗条件
    if (!this._canShowPopup(key, options?.forceShow)) {
      return;
    }

    const scenario = this.scenarios[key];

    // 记录弹窗显示
    this._recordPopup(key);

    // 显示弹窗
    return this.dialogService.open(
      options?.content || scenario.defaultContent,
      {
        label: options?.title || scenario.title,
        actions: options?.actions || scenario.defaultActions || ['确定'],
      }
    );
  }

  /**
   * 显示弹窗，支持日期和时间间隔控制（兼容旧接口）
   * @param key 弹窗的唯一标识
   * @param options 弹窗配置
   * @param dayLimit 一天内最多显示次数，默认为3
   * @param firstIntervalMinutes 第一次弹出后的间隔时间（分钟），默认为0
   * @param secondIntervalMinutes 第二次弹出后的间隔时间（分钟），默认同firstIntervalMinutes
   * @returns 弹窗操作的Observable
   */
  showDialog(
    key: string,
    options: {
      title?: string;
      content: string;
      label?: string;
      actions?: string[];
    },
    dayLimit = 3,
    firstIntervalMinutes = 0,
    secondIntervalMinutes?: number
  ) {
    // 如果该key已注册为业务场景，则使用业务场景方式显示
    if (this.scenarios[key]) {
      return this.showByScenario(key, {
        content: options.content,
        title: options.title || options.label,
        actions: options.actions,
      });
    }

    // 动态注册临时场景配置
    this.registerScenario({
      key,
      defaultContent: options.content,
      title: options.title || options.label,
      defaultActions: options.actions || ['确定'],
      maxShowPerDay: dayLimit,
      firstPopupInterval: firstIntervalMinutes,
      secondPopupInterval: secondIntervalMinutes ?? firstIntervalMinutes,
    });

    // 使用注册后的场景显示弹窗
    return this.showByScenario(key);
  }

  /**
   * 获取所有注册的业务场景
   */
  getAllScenarios(): BusinessScenarioConfig[] {
    return Object.values(this.scenarios);
  }

  /**
   * 获取下一个应该显示的业务场景（按优先级排序）
   */
  getNextScenarioToShow(): BusinessScenarioConfig | null {
    return (
      Object.values(this.scenarios)
        .filter((scenario) => this._canShowPopup(scenario.key))
        .sort((a, b) => (b.priority || 0) - (a.priority || 0))[0] || null
    );
  }

  /**
   * 获取场景当天的弹窗次数
   * @param key 业务场景唯一标识
   */
  getPopupCount(key: string): number {
    const today = this._getTodayKey();
    if (!this.popupRecords[key] || this.popupRecords[key].date !== today) {
      return 0;
    }
    return this.popupRecords[key].times.length;
  }

  /**
   * 获取场景下一次可弹窗的时间戳
   * @param key 业务场景唯一标识
   * @returns 下一次可弹窗的时间戳，0表示可以立即弹窗，-1表示今天已不能再弹窗
   */
  getNextPopupTime(key: string): number {
    const scenario = this.scenarios[key];
    if (!scenario || !scenario.enabled) {
      return -1;
    }

    const today = this._getTodayKey();

    // 确保该场景的记录对象存在
    if (!this.popupRecords[key] || this.popupRecords[key].date !== today) {
      return 0; // 今天没有弹出过，可以立即弹出
    }

    const record = this.popupRecords[key];

    // 如果已经达到当天最大弹出次数
    if (record.times.length >= (scenario.maxShowPerDay || 3)) {
      return -1; // 今天已不能再弹窗
    }

    // 如果有弹窗历史，计算下一次可弹窗的时间
    if (record.times.length > 0) {
      const lastPopupTime = record.times[record.times.length - 1];
      let intervalMinutes = 0;

      if (record.times.length === 1) {
        intervalMinutes = scenario.firstPopupInterval || 0;
      } else if (record.times.length === 2) {
        intervalMinutes =
          scenario.secondPopupInterval || scenario.firstPopupInterval || 0;
      }

      if (intervalMinutes > 0) {
        const intervalMs = intervalMinutes * 60 * 1000;
        const nextTime = lastPopupTime + intervalMs;
        const now = Date.now();

        if (nextTime > now) {
          return nextTime;
        }
      }
    }

    return 0; // 可以立即弹窗
  }

  // 私有方法：保存弹窗记录
  private _savePopupRecords() {
    try {
      localStorage.setItem(
        this.STORAGE_RECORDS_KEY,
        JSON.stringify(this.popupRecords)
      );
    } catch (error) {
      console.error('保存弹窗记录出错:', error);
    }
  }

  // 私有方法：保存场景配置
  private _saveScenarios() {
    try {
      localStorage.setItem(
        this.STORAGE_SCENARIO_KEY,
        JSON.stringify(this.scenarios)
      );
    } catch (error) {
      console.error('保存场景配置出错:', error);
    }
  }
}
